﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TempletInstaller
{
    class Program
    {
        static void Main(string[] args)
        {
            //Formaters
            string hBar = "================================================================================";
            string cat = "  |\\_/|\n / @ @ \\\n( > º < )	Thank for installing OpenCV2.2 Project Templet\n `»»x««´	--Bye bye\n /  O  \\";

            Console.BackgroundColor = ConsoleColor.White;
            Console.ForegroundColor = ConsoleColor.Blue;
            Console.Clear();

            Console.WriteLine("");
            Console.WriteLine("                 Welcome to OpenCV2.2 Project Templet Installer");
            Console.WriteLine(hBar);
            Console.WriteLine("");

            Console.Write("It will install a visual c++ project templet for your Visual Studio 2010. You must have Visul Studio 2010 and OpenCV2.2 installed to install this templet.");
            Console.WriteLine("");
            Console.WriteLine("");
            Console.Write("Press 'Y' to continue and 'N' to exit...");

            int errorcount = 0;
            while (true)
            {
                ConsoleKeyInfo key = Console.ReadKey(true);
                if (key.KeyChar.ToString().ToLower() == "n") return;
                if (key.KeyChar.ToString().ToLower() == "y") break;
                else
                {
                    if (errorcount == 0)
                    {
                        Console.WriteLine("");
                        Console.Write("I don't know whats in your mind, please choose 'Y' or 'N'....");
                    }
                    if (errorcount == 2)
                    {
                        Console.WriteLine("");
                        Console.WriteLine("");
                        Console.Write("I am patient .... (^._.^)...");
                    }
                    errorcount++;
                }
            }
            Console.WriteLine("");
            if (errorcount >= 2) Console.WriteLine("");
            errorcount = 0;
            Console.WriteLine("Thank you. Let me check if you have the required softwares.");
            Console.WriteLine("");

            //First task first. Check requirement...
            List<Directory> required = RequiredDirectories();
            bool Is64bit = false;

            if (!required[0].IsFound())
            {
                Console.WriteLine("");
                Console.WriteLine("Fatal error, I am unable to help you. Your 'Program Files' directory does not exist in 'C' drive.");
                Console.WriteLine("");
                System.Threading.Thread.Sleep(1000);
                return;
            }
            if (required[0].DirectoryName == required[0].Alternatives[0]) Is64bit = true;

            string TheJs = Properties.Resources._default;

            //Now lets check other required folders
            for (int i = 1; i < required.Count; i++)
            {
                if (!required[i].IsFound())
                {
                    Console.WriteLine("I am sorry. Please install the required softwares first. Hope to see you soon.");
                    System.Threading.Thread.Sleep(1000);
                    return;
                }
                else
                {
                    //Default.js needs to be updated for each directory
                    if (required[i].DirectoryName != required[i].Alternatives[0])
                    {
                        TheJs = TheJs.Replace(required[i].Alternatives[0].Replace("\\", "\\\\"), required[i].DirectoryName.Replace("\\", "\\\\"));
                    }
                }
            }

            Console.WriteLine("");
            Console.WriteLine("Oh!! Looks like you have them all");
            Console.WriteLine("Okay!! Let me check if you already have this templet or not.");
            Console.WriteLine("");

            bool HasAll = true;
            bool HasPart = false;


            List<Directory> TempletFolders = TempletDirectories();
            foreach (Directory d in TempletFolders)
            {
                bool isfound = d.IsFound();
                HasAll = HasAll & isfound;
                HasPart = HasPart | isfound;
                if (!isfound)
                {
                    Console.WriteLine("Creating directory...");
                    if (Is64bit) d.DirectoryName = d.Alternatives[1]; else d.DirectoryName = d.Alternatives[0];
                    System.IO.Directory.CreateDirectory(d.DirectoryName);
                }
            }

            if (HasAll)
            {
                Console.WriteLine("");
                Console.WriteLine(hBar);
                Console.WriteLine("So you have them all yah!!");
                Console.WriteLine("Templet already installed.");
                Console.WriteLine("");
                System.Threading.Thread.Sleep(3000);
                return;
            }


            Console.WriteLine("Installing files...");

            //Lets place all the files in place, one by one :)
            System.IO.File.WriteAllText(TempletFolders[3] + "\\default.js", TheJs);
            //now the rest
            System.IO.File.WriteAllText(TempletFolders[5] + "\\cvlib.h", Properties.Resources.cvlib);
            System.IO.File.WriteAllText(TempletFolders[5] + "\\main.cpp", Properties.Resources.main);
            System.IO.File.WriteAllText(TempletFolders[5] + "\\stdafx.cpp", Properties.Resources.stdafx);
            System.IO.File.WriteAllText(TempletFolders[5] + "\\stdafx.h", Properties.Resources.stdafx1);
            System.IO.File.WriteAllText(TempletFolders[5] + "\\targetver.h", Properties.Resources.targetver);
            System.IO.File.WriteAllText(TempletFolders[5] + "\\Templates.inf", Properties.Resources.Templates);

            System.IO.FileStream fs = new System.IO.FileStream(required[4] + "\\OpenCV2.2 Project.ico", System.IO.FileMode.Create);
            Properties.Resources.OpenCV2_2_Project.Save(fs);
            fs.Close();

            System.IO.File.WriteAllBytes(required[4] + "\\OpenCV2.2 Project.vsz", Properties.Resources.OpenCV2_2_Project1);

            Console.WriteLine("Files installed correctly. Finallizing setup...");

            string VisualC = System.IO.File.ReadAllText(required[4] + "\\vc.vsdir");
            string TempletText = "OpenCV2.2 Project.vsz|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#2000|100|#2001|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|0|4096|#1154";
            if (VisualC.IndexOf(TempletText) < 0)
            {
                if (VisualC[VisualC.Length - 1] != '\n') VisualC += "\n";
                VisualC += TempletText + "\n";
                System.IO.File.WriteAllText(required[4] + "\\vc.vsdir", VisualC);
            }
            Console.WriteLine("");
            Console.WriteLine("");
            Console.WriteLine("Installation completed successfully... Press any key to exit");
            Console.WriteLine(hBar);
            Console.WriteLine("");
            Console.WriteLine("");
            Console.WriteLine(cat);
            Console.ReadKey(true);
            return;
        }

        static List<Directory> TempletDirectories()
        {
            List<Directory> dirlist = new List<Directory>();

            //Application directories
            Directory app1 = new Directory();
            app1.MemberOf = "OpenCV2.2 Project";
            app1.Alternatives.Add("C:\\Program Files\\Microsoft Visual Studio 10.0\\VC\\VCWizards\\AppWiz\\OpenCV2.2");
            app1.Alternatives.Add("C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\VC\\VCWizards\\AppWiz\\OpenCV2.2");
            app1.IsRequired = false;
            dirlist.Add(app1);

            Directory app2 = new Directory();
            app2.MemberOf = "OpenCV2.2 Project";
            app2.Alternatives.Add("C:\\Program Files\\Microsoft Visual Studio 10.0\\VC\\VCWizards\\AppWiz\\OpenCV2.2\\OpenCV2.2 Project");
            app2.Alternatives.Add("C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\VC\\VCWizards\\AppWiz\\OpenCV2.2\\OpenCV2.2 Project");
            app2.IsRequired = false;
            dirlist.Add(app2);

            Directory app3 = new Directory();
            app3.MemberOf = "OpenCV2.2 Project";
            app3.Alternatives.Add("C:\\Program Files\\Microsoft Visual Studio 10.0\\VC\\VCWizards\\AppWiz\\OpenCV2.2\\OpenCV2.2 Project\\Scripts");
            app3.Alternatives.Add("C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\VC\\VCWizards\\AppWiz\\OpenCV2.2\\OpenCV2.2 Project\\Scripts");
            app3.IsRequired = false;
            dirlist.Add(app3);

            Directory app4 = new Directory();
            app4.MemberOf = "OpenCV2.2 Project";
            app4.Alternatives.Add("C:\\Program Files\\Microsoft Visual Studio 10.0\\VC\\VCWizards\\AppWiz\\OpenCV2.2\\OpenCV2.2 Project\\Scripts\\1033");
            app4.Alternatives.Add("C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\VC\\VCWizards\\AppWiz\\OpenCV2.2\\OpenCV2.2 Project\\Scripts\\1033");
            app4.IsRequired = false;
            dirlist.Add(app4);

            Directory app5 = new Directory();
            app5.MemberOf = "OpenCV2.2 Project";
            app5.Alternatives.Add("C:\\Program Files\\Microsoft Visual Studio 10.0\\VC\\VCWizards\\AppWiz\\OpenCV2.2\\OpenCV2.2 Project\\Templates");
            app5.Alternatives.Add("C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\VC\\VCWizards\\AppWiz\\OpenCV2.2\\OpenCV2.2 Project\\Templates");
            app5.IsRequired = false;
            dirlist.Add(app5);

            Directory app6 = new Directory();
            app6.MemberOf = "OpenCV2.2 Project";
            app6.Alternatives.Add("C:\\Program Files\\Microsoft Visual Studio 10.0\\VC\\VCWizards\\AppWiz\\OpenCV2.2\\OpenCV2.2 Project\\Templates\\1033");
            app6.Alternatives.Add("C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\VC\\VCWizards\\AppWiz\\OpenCV2.2\\OpenCV2.2 Project\\Templates\\1033");
            app6.IsRequired = false;
            dirlist.Add(app6);

            return dirlist;
        }

        static List<Directory> RequiredDirectories()
        {
            List<Directory> dirlist = new List<Directory>();

            //Programme Files
            Directory app1 = new Directory();
            app1.MemberOf = "Windows";
            app1.Alternatives.Add("C:\\Program Files (x86)");
            app1.Alternatives.Add("C:\\Program Files");
            app1.IsRequired = false;
            dirlist.Add(app1);

            //OpenCV2.2 Includes
            Directory inc1 = new Directory();
            inc1.MemberOf = "OpenCV2.2";
            inc1.Alternatives.Add("C:\\OpenCV2.2\\include");
            inc1.Alternatives.Add("C:\\Program Files\\OpenCV2.2\\include");
            inc1.Alternatives.Add("C:\\Program Files (x86)\\OpenCV2.2\\include");
            inc1.IsRequired = true;
            dirlist.Add(inc1);

            Directory inc2 = new Directory();
            inc2.MemberOf = "OpenCV2.2";
            inc2.Alternatives.Add("C:\\OpenCV2.2\\include\\opencv");
            inc2.Alternatives.Add("C:\\Program Files\\OpenCV2.2\\include\\opencv");
            inc2.Alternatives.Add("C:\\Program Files (x86)\\OpenCV2.2\\include\\opencv");
            inc2.IsRequired = true;
            dirlist.Add(inc2);

            //OpenCV2.2 Library
            Directory Lib1 = new Directory();
            Lib1.MemberOf = "OpenCV2.2";
            Lib1.Alternatives.Add("C:\\OpenCV2.2\\lib");
            Lib1.Alternatives.Add("C:\\Program Files\\OpenCV2.2\\lib");
            Lib1.Alternatives.Add("C:\\Program Files (x86)\\OpenCV2.2\\lib");
            Lib1.IsRequired = true;
            dirlist.Add(Lib1);

            //Visual Studio 2010 Directories
            Directory vis1 = new Directory();
            vis1.MemberOf = "Visual Studio 2010";
            vis1.Alternatives.Add("C:\\Program Files\\Microsoft Visual Studio 10.0\\VC\\vcprojects");
            vis1.Alternatives.Add("C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\VC\\vcprojects");
            vis1.IsRequired = true;
            dirlist.Add(vis1);

            Directory vis2 = new Directory();
            vis2.MemberOf = "Visual Studio 2010";
            vis2.Alternatives.Add("C:\\Program Files\\Microsoft Visual Studio 10.0\\VC\\VCWizards\\AppWiz");
            vis2.Alternatives.Add("C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\VC\\VCWizards\\AppWiz");
            vis2.IsRequired = true;
            dirlist.Add(vis2);

            return dirlist;
        }
    }

    class Directory
    {
        public string MemberOf { get; set; }
        public string DirectoryName { get; set; }
        public List<string> Alternatives = new List<string>();
        public bool IsRequired { get; set; }

        public bool IsFound()
        {
            foreach (string s in Alternatives)
            {
                Console.WriteLine("Checking: " + s);
                if (System.IO.Directory.Exists(s))
                {
                    DirectoryName = s;
                    Console.Write("-Successfull\n");
                    return true;
                }
                Console.Write("-NotFound\n");
            }
            if (IsRequired)
                Console.WriteLine("Error: " + MemberOf + " is not installed. Please re-install " + MemberOf + " and try again.");
            return false;
        }

        public override string ToString()
        {
            return DirectoryName;
        }

    }
}
